﻿using MyOCR_WPF.OCRHelper;
using MyOCR_WPF.Tool;
using MyOCR_WPF.TranslateHelper;
using MyOCR_WPF.ViewModel;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Drawing;
using System.Speech.Synthesis;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Media;
using System.Windows.Threading;

namespace MyOCR_WPF
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        Hook hook = new Hook();//钩子
        IOCR OCR;
        ITranslate translate;


        SpeechSynthesizer synthesizer = new SpeechSynthesizer();

        public OriginalForm originalForm = new OriginalForm();

        public MainWindow()
        {
            hook.KeyDownEvent += new KeyEventHandler(hook_KeyDown);
            hook.HookStart();


            InitializeComponent();
            InitializeTray();

            this.OriginalText.DataContext = originalForm;
            this.Translation.DataContext = originalForm;
        }

        #region Hook
        private void hook_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue == (int)Keys.F4)
            {
                Screenshot_Click(null, null);
            }
        }
        #endregion

        #region 托盘图标
        /// <summary>
        /// 初始化托盘图标
        /// </summary>
        private void InitializeTray()
        {
            NotifyIcon ni = new NotifyIcon();
            ni.Icon = new Icon("MyOCR.ico");
            ni.Visible = true;
            ni.DoubleClick +=
                delegate (object sender, EventArgs args)
                {
                    this.Show();
                    this.WindowState = WindowState.Normal;
                    this.ShowInTaskbar = true;
                };
            ni.ContextMenu = new ContextMenu();
            var menu = ni.ContextMenu.MenuItems;
            menu.Add("MyOCR_WPF");
            menu.Add("截图识别", delegate (object sender, EventArgs args)
            {
                Screenshot_Click(null, null);
            });
            menu.Add("退出程序", delegate (object sender, EventArgs args)
            {
                this.Close();
            });
        }
        #endregion


        /// <summary>
        /// 获取屏幕图片
        /// </summary>
        /// <returns></returns>
        public Bitmap GetScreenSnapshot()
        {
            try
            {
                System.Drawing.Rectangle rc = SystemInformation.VirtualScreen;
                var bitmap = new Bitmap(rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

                using (Graphics memoryGrahics = Graphics.FromImage(bitmap))
                {
                    memoryGrahics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy);
                }

                return bitmap;
            }

            catch (Exception)
            {

            }
            return null;
        }

        /// <summary>
        /// 通过委托的方式 获取截取的图片
        /// </summary>
        /// <param name="image"></param>
        public void RecevieImg(Image image)
        {
            img.Source = ImageProcessing.ToBitmapSource(new Bitmap(image));
        }

        //截图按钮 获取并设置识别返回的内容
        private void Screenshot_Click(object sender, RoutedEventArgs e)
        {
            this.Hide();

            Thread.Sleep(500);

            var screenSnapshot = GetScreenSnapshot();
            var bmp = ImageProcessing.ToBitmapSource(screenSnapshot);
            bmp.Freeze();

            Clipper clipper = new Clipper();
            clipper.bitmap = screenSnapshot;
            clipper.sendImg = RecevieImg;//将方法赋值给委托
            clipper.Background = new ImageBrush(bmp);
            clipper.ShowDialog();

            var callback = Dispatcher.BeginInvoke(new Action(() =>
            {
                //获取数据
                originalForm.originalContent = OCR.SendImg(ImageProcessing.ImageSourceToBitmap(img.Source)).Trim().Replace(".", ". \r\n\r\n    ");
            }));

            callback.Completed += Callback_Completed;

        }

        //OCR识别后回调方法 
        private void Callback_Completed(object sender, EventArgs e)
        {
            //判断是否需要自动翻译
            if (autoTranslate.IsChecked.Value)
            {
                TranslateContent().Completed += delegate (object sender, EventArgs args)
                {
                    //是否需要预览框
                    if (isPreview.IsChecked.Value)
                    {
                        //判断是否已经存在预览框 有则关闭
                        foreach (Window window in System.Windows.Application.Current.Windows)
                        {
                            if (window.Title == "Preview")
                            {
                                window.Close();
                            }
                        }
                        new Preview().Show();
                    }

                };
            }

            if (this.ShowInTaskbar)
            {
                this.Show();
            }
        }

        //切换OCR引擎
        private void OCR_ComboBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            var selectOCR = OCR_ComboBox.SelectedValue;

            switch (selectOCR)
            {
                case "百度OCR":
                    OCR = new BaiduOCR();
                    break;
                case "有道OCR":
                    OCR = new YouDaoOCR();
                    break;
                case "搜狗OCR":
                    OCR = new SouGouOCR();
                    break;
                case "腾讯OCR":
                    OCR = new TengXunOCR();
                    break;
                default:
                    OCR = new YouDaoOCR();
                    break;
            }
        }

        //切换翻译引擎
        private void Translate_ComboBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            var selectTranslate = Translate_ComboBox.SelectedValue;

            switch (selectTranslate)
            {
                case "百度翻译":
                    translate = new BaiduTranslate();
                    break;
                case "有道翻译":
                    translate = new YouDaoTranslate();
                    break;
                case "搜狗翻译":
                    translate = new SouGouTranslate();
                    break;
                case "腾讯翻译":
                    translate = new TengXunTranslate();
                    break;
                default:
                    translate = new BaiduTranslate();
                    break;
            }
        }

        //翻译按钮
        private void Translate_Click(object sender, RoutedEventArgs e)
        {
            TranslateContent();
        }

        //自动翻译选项框 改变时
        private void autoTranslate_Checked(object sender, RoutedEventArgs e)
        {
            if (autoTranslate.IsChecked.Value && OriginalText.Text.Trim() != "")
            {
                Translate_Click(null, null);
            }
        }

        //窗口关闭时
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = true;
            this.ShowInTaskbar = false;
            this.WindowState = WindowState.Minimized;
            this.Visibility = Visibility.Hidden;
        }

        /// <summary>
        /// 翻译功能
        /// </summary>
        private DispatcherOperation TranslateContent()
        {
            DispatcherOperation callback = Dispatcher.BeginInvoke(new Action(() =>
            {
                originalForm.translationContent = translate.SendContent(OriginalText.Text);

                //朗读 只读翻译框的内容 后续改动时可以删掉
                if (autoSpeak.IsChecked.Value)
                {
                    synthesizer.Volume = 100;   //音量 0~100   最大只能100
                    synthesizer.SelectVoice("Microsoft Huihui Desktop");
                    synthesizer.SpeakAsyncCancelAll();
                    //异步朗读
                    synthesizer.SpeakAsync(Translation.Text);
                }
            }));

            return callback;
        }
    }
}
